Modal Dialog
<tpg-modal-dialog></tpg-modal-dialog>Modal Dialogs can be Global or Local used to: Provide information to user about a task or an event Prompt the user about to confirm or cancel a task or an event, directly or with a dependency
Modal Dialogs are disruptive, only use them when you need the user’s full attention for the action they are trying to accomplish. They are task-oriented workflows containing the steps the user must take to accomplish a task.
When Local:
They usually appear aligned to the center of the Workflow Panel over a “Background Overlay”. When Local Modals, are summoned by a Footer action, they can also appear aligned with the bottom of the Workflow Panel (its Footer).
When global:
They disable all system functionality when they appear, and remain on screen. They require the user to take an action in order to dismiss them, they should not disappear on their own.
Their footer follows the rules of the Modal Footer component.
How to use a confirmation dialog:
They should inform the user before commit to actions with serious consequences. They should be specific and inform users about the consequence of their action. No “Yes/No”, provide options that summarize what will happen for each response.
Guidelines
Local Modal Dialogs have: min-height: 260px min-width: 344px
Local modal Dialogs cant be used for single action choice.
A left/right padding of 12px shall always be maintained.
Default behavior
By default the modals allow-scroll attribute is set to false. This means that the
modal will prevent the background from scrolling when it is open. If you want
to allow the background to scroll, you can set the allow-scroll attribute.
Close the modal by clicking on the backdrop or pressing the escape key. You can also close the modal by clicking the close button in the header if it is present.
When in global mode, which is the default, the modal will have a focus trap. This means that when the modal is open, the focus will be trapped inside the modal. The user will not be able to tab out of the modal until it is closed. This is useful for accessibility purposes, as it ensures that the user can only interact with the modal and not the background content.
Default keyboardnavigation is enabled. This means that the user can use the tab key to navigate through the modal and the enter key to select an option. The user can also use the escape key to close the modal.
Examples
Basic
<tpg-primary-button id="openbasicModal" label="Open Basic Modal"></tpg-primary-button><tpg-modal-dialog id="basicModal" label="Confirm action" secondary-label="Are you sure you want to proceed with this action? This cannot be undone."> <tpg-footer emphasis="no-background" slot="footer" > <tpg-secondary-button id="closeBasicModal" slot="left-button" label="Cancel" ></tpg-secondary-button> <tpg-primary-button id="confirmBasicModal" label="Confirm" slot="right-button" ></tpg-primary-button> </tpg-footer></tpg-modal-dialog>
<script> document.addEventListener('DOMContentLoaded', () => { openbasicModal.addEventListener('tpg-click', () => { basicModal.showModal(); }); });</script> function SomeComponent() { const dialogRef = useRef(null);
function handleOpen() { const d = dialogRef.current! as ModalDialog; d.showModal(); }
return ( <> <tpg-primary-button label="Open Basic Modal" ontpg-click={handleOpen} ></tpg-primary-button> <tpg-modal-dialog label="Confirm action" secondaryLabel="Are you sure you want to proceed with this action? This cannot be undone." ref={dialogRef} ontpg-open={() => console.log("opened")} ontpg-close={() => console.log("closed")} > <tpg-footer emphasis="no-background" slot="footer"> <tpg-secondary-button label="Cancel" slot="left-button" ></tpg-secondary-button> <tpg-primary-button label="Confirm" slot="right-button" ></tpg-primary-button> </tpg-footer> </tpg-modal-dialog> </> ); }With close-button header
The modals show-close-button attribute is used to control if the modal should
have a header or not. The header contains a close button.
<tpg-primary-button id="opencloseModal" label="Open Header Modal"></tpg-primary-button><tpg-modal-dialog id="closeModal" label="Confirm action" show-close-button secondary-label="Are you sure you want to proceed with this action? This cannot be undone."> <tpg-footer emphasis="no-background" slot="footer" > <tpg-secondary-button id="closeBasicModal" label="Cancel" slot="left-button" ></tpg-secondary-button> <tpg-primary-button id="confirmBasicModal" label="Confirm" slot="right-button" ></tpg-primary-button> </tpg-footer></tpg-modal-dialog>
<script> document.addEventListener('DOMContentLoaded', () => { opencloseModal.addEventListener('tpg-click', () => { closeModal.showModal(); }); });</script> function SomeComponent() { const dialogRef = useRef(null);
function handleOpen() { const d = dialogRef.current! as ModalDialog; d.showModal(); }
return ( <> <tpg-primary-button label="Open Header Modal" ontpg-click={handleOpen} ></tpg-primary-button> <tpg-modal-dialog label="Confirm action" showCloseButton secondaryLabel="Are you sure you want to proceed with this action? This cannot be undone." ref={dialogRef} ontpg-open={() => console.log("opened")} ontpg-close={() => console.log("closed")} > <tpg-footer emphasis="no-background" slot="footer"> <tpg-secondary-button label="Cancel" slot="left-button"></tpg-secondary-button> <tpg-primary-button label="Confirm" slot="right-button"></tpg-primary-button> </tpg-footer> </tpg-modal-dialog> </> ); }With icon
The modals icon-template attribute is used to set the icon of the modal.
<tpg-primary-button id="openiconModal" label="Open Icon Modal"></tpg-primary-button><tpg-modal-dialog id="iconModal" label="Confirm action" icon-template={tpgIconPlaceholderCustom} show-close-button secondary-label="Are you sure you want to proceed with this action? This cannot be undone."> <tpg-footer emphasis="no-background" slot="footer" > <tpg-secondary-button id="closeBasicModal" label="Cancel" slot="left-button" ></tpg-secondary-button> <tpg-primary-button id="confirmBasicModal" label="Confirm" slot="right-button" ></tpg-primary-button> </tpg-footer></tpg-modal-dialog>
<script> document.addEventListener('DOMContentLoaded', () => { openiconModal.addEventListener('tpg-click', () => { iconModal.showModal(); }); });</script> function SomeComponent() { const dialogRef = useRef(null);
function handleOpen() { const d = dialogRef.current! as ModalDialog; d.showModal(); }
return ( <> <tpg-primary-button label="Open Icon Modal" ontpg-click={handleOpen} ></tpg-primary-button> <tpg-modal-dialog label="Confirm action" showCloseButton iconTemplate={tpgIconPlaceholderCustom} secondary-label="Are you sure you want to proceed with this action? This cannot be undone." ref={dialogRef} ontpg-open={() => console.log("opened")} ontpg-close={() => console.log("closed")} > <tpg-footer emphasis="no-background" slot="footer"> <tpg-secondary-button label="Cancel" slot="left-button" ></tpg-secondary-button> <tpg-primary-button label="Confirm" slot="right-button" ></tpg-primary-button> </tpg-footer> </tpg-modal-dialog> </> ); }Types (criticality indication)
The modals type attribute is used to set the visual type of the modal, since
footer is slotted, you will however need to set its criticality separately.
Danger
<tpg-primary-button id="opendangerModal" label="Open Danger Modal"></tpg-primary-button><tpg-modal-dialog id="dangerModal" label="Confirm action" icon-template={tpgIconPlaceholderCustom} show-close-button type="danger" secondary-label="Are you sure you want to proceed with this action? This cannot be undone."> <tpg-footer emphasis="no-background" slot="footer" > <tpg-secondary-button id="closeBasicModal" label="Cancel" slot="left-button" ></tpg-secondary-button> <tpg-primary-button id="confirmBasicModal" label="Confirm" type="danger" slot="right-button" ></tpg-primary-button> </tpg-footer></tpg-modal-dialog>
<script> document.addEventListener('DOMContentLoaded', () => { opendangerModal.addEventListener('tpg-click', () => { dangerModal.showModal(); }); });</script> function SomeComponent() { const dialogRef = useRef(null);
function handleOpen() { const d = dialogRef.current! as ModalDialog; d.showModal(); }
return ( <> <tpg-primary-button label="Open Danger Modal" ontpg-click={handleOpen} ></tpg-primary-button> <tpg-modal-dialog label="Confirm action" showCloseButton iconTemplate={tpgIconPlaceholderCustom} secondaryLabel="Are you sure you want to proceed with this action? This cannot be undone." type="danger" ref={dialogRef} ontpg-open={() => console.log("opened")} ontpg-close={() => console.log("closed")} > <tpg-footer emphasis="no-background" slot="footer"> <tpg-secondary-button label="Cancel" slot="left-button" ></tpg-secondary-button> <tpg-primary-button label="Confirm" type="danger" slot="right-button" ></tpg-primary-button> </tpg-footer> </tpg-modal-dialog> </> ); }Error
<tpg-primary-button id="openerrorModal" label="Open Error Modal"></tpg-primary-button><tpg-modal-dialog id="errorModal" label="Confirm action" icon-template={tpgIconPlaceholderCustom} show-close-button type="error" secondary-label="Are you sure you want to proceed with this action? This cannot be undone."> <tpg-footer emphasis="no-background" slot="footer" > <tpg-secondary-button id="closeBasicModal" label="Cancel" slot="left-button" ></tpg-secondary-button> <tpg-primary-button id="confirmBasicModal" label="Confirm" type="error" slot="right-button" ></tpg-primary-button> </tpg-footer></tpg-modal-dialog>
<script> document.addEventListener('DOMContentLoaded', () => { openerrorModal.addEventListener('tpg-click', () => { errorModal.showModal(); }); });</script> function SomeComponent() { const dialogRef = useRef(null);
function handleOpen() { const d = dialogRef.current! as ModalDialog; d.showModal(); }
return ( <> <tpg-primary-button label="Open Error Modal" ontpg-click={handleOpen} ></tpg-primary-button> <tpg-modal-dialog label="Confirm action" showCloseButton iconTemplate={tpgIconPlaceholderCustom} secondaryLabel="Are you sure you want to proceed with this action? This cannot be undone." type="error" ref={dialogRef} ontpg-open={() => console.log("opened")} ontpg-close={() => console.log("closed")} > <tpg-footer emphasis="no-background" slot="footer"> <tpg-secondary-button label="Cancel" slot="left-button" ></tpg-secondary-button> <tpg-primary-button label="Confirm" type="error" slot="right-button" ></tpg-primary-button> </tpg-footer> </tpg-modal-dialog> </> ); }Ignore click outside
The modal will by default close when user clicks outside it. You can override this behavior with the preventCloseOnClickOutside
attribute.
<tpg-primary-button id="openignoreClickOutsideModal" label="Open Ignore Click Outside Modal"></tpg-primary-button><tpg-modal-dialog id="ignoreClickOutsideModal" label="Confirm action" icon-template={tpgIconPlaceholderCustom} prevent-close-on-click-outside show-close-button secondary-label="Are you sure you want to proceed with this action? This cannot be undone."> <tpg-footer emphasis="no-background" slot="footer" class="not-content"> <tpg-secondary-button id="closeBasicModal" label="Cancel" slot="left-button"> </tpg-secondary-button> <tpg-primary-button id="confirmBasicModal" label="Confirm" slot="right-button"> </tpg-primary-button> </tpg-footer></tpg-modal-dialog>
<script> document.addEventListener('DOMContentLoaded', () => { openignoreClickOutsideModal.addEventListener('tpg-click', () => { ignoreClickOutsideModal.showModal(); }); });</script> function SomeComponent() { const dialogRef = useRef(null);
function handleOpen() { const d = dialogRef.current! as ModalDialog; d.showModal(); }
return ( <> <tpg-primary-button label="Open Ignore Click Outside Modal" ontpg-click={handleOpen} ></tpg-primary-button> <tpg-modal-dialog label="Confirm action" showCloseButton iconTemplate={tpgIconPlaceholderCustom} secondaryLabel="Are you sure you want to proceed with this action? This cannot be undone." ref={dialogRef} ontpg-open={() => console.log("opened")} ontpg-close={() => console.log("closed")} > <tpg-footer emphasis="no-background" slot="footer"> <tpg-secondary-button label="Cancel" slot="left-button" ></tpg-secondary-button> <tpg-primary-button label="Confirm" slot="right-button" ></tpg-primary-button> </tpg-footer> </tpg-modal-dialog> </> ); }Open in local mode
The modals positioning attribute is used to set the modals positioning. The
positioning attribute can be set to local or global. The default value is
global.
In local mode, the modal will be positioned relative to the nearest parent element with positioning set to relative. In global mode, the modal will be positioned relative to the viewport.
<tpg-primary-button id="openlocalModal" label="Open Local Modal"></tpg-primary-button><div style="width: 600px; height: 400px; position: relative; background-color: #f0f0f0;"> <tpg-modal-dialog id="localModal" label="Local Modal" positioning="local" icon-template={tpgIconPlaceholderCustom} show-close-button secondary-label="Im relative to my parent element." > <tpg-footer emphasis="no-background" slot="footer" > <tpg-secondary-button id="closeBasicModal" label="Cancel" slot="left-button" ></tpg-secondary-button> <tpg-primary-button id="confirmBasicModal" label="Confirm" slot="right-button" ></tpg-primary-button> </tpg-footer> </tpg-modal-dialog></div>
<script> document.addEventListener('DOMContentLoaded', () => { openlocalModal.addEventListener('tpg-click', () => { localModal.showModal(); }); });</script> function SomeComponent() { const dialogRef = useRef(null);
function handleOpen() { const d = dialogRef.current! as ModalDialog; d.showModal(); }
return ( <> <tpg-primary-button label="Open Local Modal" ontpg-click={handleOpen} ></tpg-primary-button> <div style={{ width: "600px", height: "400px", position: "relative", backgroundColor: "#f0f0f0", }} > <tpg-modal-dialog label="Local Modal" positioning="local" iconTemplate={tpgIconPlaceholderCustom} showCloseButton secondaryLabel="Im relative to my parent element." ref={dialogRef} ontpg-open={() => console.log("opened")} ontpg-close={() => console.log("closed")} > <tpg-footer emphasis="no-background" slot="footer"> <tpg-secondary-button label="Cancel" slot="left-button" ></tpg-secondary-button> <tpg-primary-button label="Confirm" slot="right-button" ></tpg-primary-button> </tpg-footer> </tpg-modal-dialog> </div> </> ); }Adding content with slots
The modals content slot is reserved for the content of the modal. The content
can be any HTML element.
This is a custom content slot
It can contain any HTML element
It can also contain other components
<tpg-primary-button id="opencontentModal" label="Open Content Modal"></tpg-primary-button><tpg-modal-dialog id="contentModal" label="Global Modal with content slot" icon-template={tpgIconPlaceholderCustom} show-close-button> <div slot="content"> <p>This is a custom content slot</p> <p>It can contain any HTML element</p> <p>It can also contain other components</p> <tpg-text-field id="textField" label="Text Field" placeholder="This is a text field" value="This is a text field" ></tpg-text-field> </div> <tpg-footer emphasis="no-background" slot="footer" > <tpg-secondary-button id="closeBasicModal" label="Cancel" slot="left-button" ></tpg-secondary-button> <tpg-primary-button id="confirmBasicModal" label="Confirm" slot="right-button" ></tpg-primary-button> </tpg-footer></tpg-modal-dialog>
<script> document.addEventListener('DOMContentLoaded', () => { opencontentModal.addEventListener('tpg-click', () => { contentModal.showModal(); }); });</script> function SomeComponent() { const dialogRef = useRef(null);
function handleOpen() { const d = dialogRef.current! as ModalDialog; d.showModal(); }
return ( <> <tpg-primary-button label="Open Content Modal" ontpg-click={handleOpen} ></tpg-primary-button> <tpg-modal-dialog label="Global Modal with content slot" iconTemplate={tpgIconPlaceholderCustom} showCloseButton ref={dialogRef} ontpg-open={() => console.log("opened")} ontpg-close={() => console.log("closed")} > <div slot="content"> <p>This is a custom content slot</p> <p>It can contain any HTML element</p> <p>It can also contain other components</p> <tpg-text-field label="Text Field" placeholder="This is a text field" value="This is a text field" ></tpg-text-field> </div> <tpg-footer emphasis="no-background" slot="footer"> <tpg-secondary-button label="Cancel" slot="left-button" ></tpg-secondary-button> <tpg-primary-button label="Confirm" slot="right-button" ></tpg-primary-button> </tpg-footer> </tpg-modal-dialog> </> ); }Slots
The modal dialog has a slot for the content. The content can be any HTML element. The modal dialog also has a slot for the footer. The footer slot is reserved for the tpg-footer component.
Tables
Properties
| Attribute | Property | Description | Type | Default Value |
|---|---|---|---|---|
| show-close-button | showCloseButton | If the modal should have a close button in the top right corner or not. | boolean | false |
| icon-template | iconTemplate | URI-encoded SVG of icon to appear above the text. | IconConstant | '' | '' |
| label | label | The main text to be displayed in the modal. | string | '' |
| secondary-label | secondaryLabel | Secondary text to be displayed in the modal. | string | '' |
| is-open | isOpen | Whether or not the modal is open. Note: its recommended to open and close the modal through js methodes showModal() and close(); | boolean | false |
| positioning | positioning | Determines the positioning of the modal: "global" for centering on the screen, "local" for centering within a parent container. | 'global' | 'local' | 'global' |
| allow-scroll | allowScroll | If the modal should prevent scrolling of the background when open. | boolean | false |
| prevent-close-on-click-outside | preventCloseOnClickOutside | Prevents the modal from closing when clicking outside. | boolean | false |
| type | type | Visual type of the modal dialog. Affects the color of icon and label according to criticality. | 'default' | 'error' | 'danger' | 'default' |
Events
| Event name | Reactjs attribute | Description |
|---|---|---|
| tpg-close | ontpg-close | emitted when closing the modal |
| tpg-show | ontpg-show | emitted when opening the modal |
Functions
| Name | Description | Arguments |
|---|---|---|
| showModal | Opens the dialog - for consumers. | No parameters |
| hideModal | Closes the dialog - for consumers. | No parameters |
Slots
| Name | Description |
|---|---|
| content | slot reserved for custom content |
| footer | slot reserved for a tpg-footer component |
CSS Parts
| Attribute | Description |
|---|---|
| content | part for adding styling to the default slot |
| footer | part for adding styling to the footer slot |