Avi Rai
Lightning Modal module in LWC
What is Modal?
A modal overlays a popup on top of the current app window. This paradigm is used in cases such as the creation or editing of a record, as well as various types of messaging and wizards. A modal is triggered by user interaction, which can be a click of a button or link. The user must then interact with the modal before regaining control over the app window.
Current practice to create a modal in LWC
We use Lightning Design System and Overlay Library to create modals currently. They work perfectly however we have to write a lot of lines of code to get the work done.
LightningModal module
With the Winter'23 release, we now have a Lightning Modal module that we can directly use to create a modal in LWC with very minimum effort and fewer lines of code. It implements the SLDS modal blueprint. There is no lightning-modal component. Instead, you create a modal by extending LightningModal and using the helper lightning-modal-* components to provide a header, footer and the body of the modal.
The component has access to the normal LWC resources as well as the special container, helper components, methods, and events of the lightning/modal module.
Play with it
import LightningModal from lightning/modal
The modal’s HTML template uses helper lightning-modal-* components to provide a header, footer, and the body of the modal. The lightning-modal-body component is required for the modal template.
Open a modal instance - LightningModal provides an .open() method. Each invocation of a modal component’s .open() method creates a unique instance of the modal. The .open() method lets you assign values to the modal's properties - [label, size, description, disableClose].
Close a modal instance - Use this.close(result) to close the modal, where the result is anything you want to return from the modal. You can also close the modal with the default close button, the X at the top right corner. Closing a modal like this is the same as calling this.close() with an undefined result, so any data input is lost.
Example - An LWC myModal using Lightning Modal that is used to create an Account record. It is called from a parent LWC myComponent.
myComponent - It comprises a button Create Account which creates an instance of myModal using .open() method with the properties size and description. It also displays the result passed by myModal on close.
myComponent.html
<template>
<lightning-button label="Create Account" onclick={openAccountModal}></lightning-button>
<p>Result : {result}</p>
</template>
myComponent.js
import { LightningElement } from 'lwc';
import MyModal from 'c/myModal';
export default class MyComponent extends LightningElement {
result;
async openAccountModal() {
this.result = await MyModal.open({
size: 'medium',
description: 'Gets the Account data and creates Account record'
});
console.log(this.result);
}
}
myModal - It extends the LightningModule and uses lightning-modal-* components for header, footer and body of the modal. It creates the account record and on close returns the Id of the account created to the parent component.
myModal.html
<template>
<lightning-modal-header label="Create Account"></lightning-modal-header>
<lightning-modal-body>
<lightning-record-edit-form object-api-name="Account" onsuccess={handleSuccess}>
<lightning-input-field field-name="Name"></lightning-input-field>
</lightning-record-edit-form>
</lightning-modal-body>
<lightning-modal-footer>
<lightning-button label="Submit" onclick={createAccount}></lightning-button>
</lightning-modal-footer>
</template>
myModal.js
import LightningModal from 'lightning/modal';
export default class MyModal extends LightningModal {
createAccount() {
this.template.querySelector('lightning-record-edit-form').submit();
}
handleSuccess(event) {
const createdRecord = event.detail.id;
console.log('onsuccess: ', createdRecord);
this.close(createdRecord);
}
}
Thanks for reading and keep learning!