sp-dialog-base
NPM 1.9.0
View Storybook
Try it on Stackblitz
Overview
DialogBase is a foundational class that handles the core functionality of displaying and managing dialog content in an overlay. This base class provides the foundation for more specific dialog implementations like sp-dialogsp-dialog-wrapper
Usage
yarn add @spectrum-web-components/dialog
Import the side effectful registration of <sp-dialog-base> via:
import '@spectrum-web-components/dialog/sp-dialog-base.js';
When looking to leverage the DialogBase base class as a type and/or for extension purposes, do so via:
import { DialogBase } from '@spectrum-web-components/dialog';
Anatomy
The sp-dialog-base element is a wrapper that provides animation and positioning for the dialog content.
The dialog base manages several behaviors:
- Animation of the dialog content when opening/closing
- Focus management when the dialog opens
- Event handling for closing the dialog
Use DialogBase when:
- You need to present important information that requires user acknowledgment
- You're building a modal interface that blocks interaction with the page
- You need a structured container with features like backdrop/underlay
- Your content is complex and requires formal layout with headings, content sections, and actions
Use an sp-popover
- You need a lightweight, contextual container that's positioned relative to a trigger element
- You want to display simple content like menus, tooltips, or additional options
- You're building a non-modal interface where users can still interact with the page
- You need an element with an arrow/tip pointing to the trigger
<overlay-trigger type="modal"> <sp-dialog-base underlay slot="click-content"> <sp-dialog> <h2 slot="heading">A thing is about to happen</h2> <p>Something that might happen a lot is about to happen.</p> <p> The click events for the "OK" button are bound to the story not to the components in specific. </p> <sp-button variant="secondary" treatment="fill" slot="button" onclick="this.dispatchEvent(new Event('close', { bubbles: true, composed: true }));" > Ok </sp-button> <sp-checkbox slot="footer">Don't show me this again</sp-checkbox> </sp-dialog> </sp-dialog-base> <sp-button slot="trigger" variant="primary">Toggle Dialog</sp-button> </overlay-trigger>
Options
Underlay
The underlay attribute can be used to add an underlay element between the page content and the dialog.
<overlay-trigger type="modal"> <sp-dialog-base underlay slot="click-content"> <sp-dialog> <h2 slot="heading">A thing is about to happen</h2> <p>Something that might happen a lot is about to happen.</p> <sp-button variant="secondary" treatment="fill" slot="button" onclick="this.dispatchEvent(new Event('close', { bubbles: true, composed: true }));" > Ok </sp-button> </sp-dialog> </sp-dialog-base> <sp-button slot="trigger" variant="primary">Toggle Dialog</sp-button> </overlay-trigger>
<overlay-trigger type="modal"> <sp-dialog-base slot="click-content"> <sp-dialog> <h2 slot="heading">A thing is about to happen</h2> <p>Something that might happen a lot is about to happen.</p> <sp-button variant="secondary" treatment="fill" slot="button" onclick="this.dispatchEvent(new Event('close', { bubbles: true, composed: true }));" > Ok </sp-button> </sp-dialog> </sp-dialog-base> <sp-button slot="trigger" variant="primary">Toggle Dialog</sp-button> </overlay-trigger>
Dismissable
The dismissable attribute can be used to add an underlay element between the page content and the dialog.
<overlay-trigger type="modal"> <sp-dialog-base dismissable slot="click-content"> <sp-dialog> <h2 slot="heading">A thing is about to happen</h2> <p>Something that might happen a lot is about to happen.</p> </sp-dialog> </sp-dialog-base> <sp-button slot="trigger" variant="primary">Toggle Dialog</sp-button> </overlay-trigger>
<overlay-trigger type="modal"> <sp-dialog-base underlay slot="click-content"> <sp-dialog> <h2 slot="heading">A thing is about to happen</h2> <p>Something that might happen a lot is about to happen.</p> <sp-button variant="secondary" treatment="fill" slot="button" onclick="this.dispatchEvent(new Event('close', { bubbles: true, composed: true }));" > Ok </sp-button> </sp-dialog> </sp-dialog-base> <sp-button slot="trigger" variant="primary">Toggle Dialog</sp-button> </overlay-trigger>
Mode
The dialog base supports different display modes: fullscreen and fullscreenTakeover.
<overlay-trigger type="modal"> <sp-dialog-base mode="fullscreen" slot="click-content"> <sp-dialog> <h2 slot="heading">A thing is about to happen</h2> <p>Something that might happen a lot is about to happen.</p> <sp-button variant="secondary" treatment="fill" slot="button" onclick="this.dispatchEvent(new Event('close', { bubbles: true, composed: true }));" > Ok </sp-button> </sp-dialog> </sp-dialog-base> <sp-button slot="trigger" variant="primary">Toggle Dialog</sp-button> </overlay-trigger>
<overlay-trigger type="modal"> <sp-dialog-base mode="fullscreenTakeover" slot="click-content"> <sp-dialog> <h2 slot="heading">A thing is about to happen</h2> <p>Something that might happen a lot is about to happen.</p> <sp-button variant="secondary" treatment="fill" slot="button" onclick="this.dispatchEvent(new Event('close', { bubbles: true, composed: true }));" > Ok </sp-button> </sp-dialog> </sp-dialog-base> <sp-button slot="trigger" variant="primary">Toggle Dialog</sp-button> </overlay-trigger>
Extending DialogBase
Extend the dialog base to create a new component that uses the same base functionality but with additional features.
sp-dialog-base expects a single slotted child element to play the role of the dialog that it will deliver within your application. When leveraging it as a base class be sure to customize the dialog getter to ensure that it acquires the appropriate element for your use case in order to correctly pass focus into your content when the dialog is opened.
See DialogWrapper.ts
import { DialogBase } from '@spectrum-web-components/dialog'; export class MyCustomDialogWrapper extends DialogBase { public static override get styles(): CSSResultArray { return [...super.styles]; protected override renderDialog(): TemplateResult { return html` <my-custom-dialog> <slot></slot> </my-custom-dialog> `; } protected override get dialog(): Dialog { return this.shadowRoot.querySelector('my-custom-dialog') as Dialog; } }
Accessibility
Include a heading
The heading slot is of the sp-dialog dialog element is used to label the dialog content for screen readers.
Manage focus
The dialog base component ensures proper focus management by:
- Moving focus into the dialog when opened
- Trapping tab order within the dialog while open
- Returning focus to the trigger element when closed
The receives-focus attribute can be used to control whether the dialog should receive focus when it is opened. Leverage the type="modal" and receives-focus="auto" settings in the Overlay API to ensure that focus is thrown into the dialog content when opened and that the tab order will be trapped within it while open.
The receives-focus attribute on overlay-trigger has three possible values:
auto(default): Focus will automatically move to the first focusable element in the dialogtrue: Forces focus to move to the overlay contentfalse: Prevents focus from moving to the overlay
<overlay-trigger type="modal" receives-focus="true"> <sp-dialog-base mode="fullscreenTakeover" slot="click-content"> <sp-dialog> <h2 slot="heading">A thing is about to happen</h2> <p>Something that might happen a lot is about to happen.</p> <sp-button variant="secondary" treatment="fill" slot="button" onclick="this.dispatchEvent(new Event('close', { bubbles: true, composed: true }));" > Ok </sp-button> </sp-dialog> </sp-dialog-base> <sp-button slot="trigger" variant="primary">Toggle Dialog</sp-button> </overlay-trigger>
API
Attributes and Properties
dismissable dismissable boolean false mode mode 'fullscreen' | 'fullscreenTakeover' | undefined open open boolean false responsive responsive boolean false underlay underlay boolean false Slots
default slot Events
close Event Announces that the dialog has been closed. undefined TransitionEvent