I have created a component(modalParent) having lightning modal(myModal) using SLDS. When the modal is opened, ideally it should get auto focus but that is not happening. The focus is on the background interactive items.
I want the focus to move to modal. I have tried setting focus to heading inside modal using javascript focus in renderedCallback but that is also not working as nothing gets displayed when renderedCallback is called.
modalParent.html
<template>
<div class="slds-form-element slds-form-element_stacked">
<label class="slds-form-element__label">"Parent Modal"</label>
<!-- Modal Component -->
<template if:true={isModalOpen}>
<c-my-modal onclose={handleModalClose} content={_value} class="parentFromModal"></c-my-modal>
</template>
<div class="slds-form-element__control odc-rich-text" disabled={disabled} title="edit">
<!-- Editable when not disabled -->
<template if:false={disabled}>
<a href="javascript:void(0);"
class="slds-box odc-rich-text-action rich-text-container"
onclick={openModal}
aria-label={_ariaLabel}
role = "button"
title="Edit Rich Text Content">
<lightning-formatted-rich-text value={_value}></lightning-formatted-rich-text>
</a>
</template>
<!-- Non-clickable view when disabled -->
<template if:true={disabled}>
<div class="slds-box odc-rich-text-action">
<lightning-formatted-rich-text value={_value}></lightning-formatted-rich-text>
</div>
</template>
</div>
</div>
</template>
modalParent.js
import { api, track, LightningElement } from 'lwc';
export default class ModalParent extends LightningElement {
@api disabled;
@api label;
@api fieldLevelHelp;
_value;
@track isModalOpen = false;
@api get value() {
return this._value;
}
set value(value) {
this._value = value;
}
disabled = false;
label = "Instructions Label"
renderedCallback() {
}
openModal() {
this.isModalOpen = true;
}
handleModalClose(event) {
const newValue = event.detail;
if (newValue !== null && newValue !== undefined && newValue !== this._value) {
this._value = newValue;
this.dispatchEvent(new CustomEvent('change'));
}
this.isModalOpen = false;
}
}
myModal.html
<template>
<div class="slds-modal slds-fade-in-open odc_modal" role="dialog" aria-label="I am aria label" aria-labelledby="modal-heading-01" aria-modal="true" aria-describedby="modal-content-id-1" onkeydown={handleKeyDown} tabindex="0">
<div class="slds-modal__container" tabindex="-1">
<header class="slds-modal__header">
<h2 class="slds-text-heading_medium">My Modal</h2>
<button class="slds-button slds-button_icon slds-modal__close slds-button_icon-inverse" title="Close" onclick={handleCancel}>
<lightning-icon icon-name="utility:close" alternative-text="Close" size="small"></lightning-icon>
</button>
</header>
<div class="slds-modal__content slds-p-around_medium" id="modal-content-id-1">
<lightning-button onclick={handleOptionClick}>
ButtonLabel
</lightning-button>
</div>
<footer class="slds-modal__footer">
<lightning-button label="Cancel" onclick={handleCancel}></lightning-button>
<lightning-button label="Save" variant="brand" onclick={handleSave}></lightning-button>
</footer>
</div>
</div>
<div class="slds-backdrop slds-backdrop_open" role="presentation"></div>
</div>
</template>
myModal.js
import { LightningElement, api } from 'lwc';
export default class MyModal extends LightningElement {
@api content = '';
handleKeyDown(event) {
event.stopPropagation();
const cardElement = this.template.querySelector('.odc_modal');
console.log("Printing the data");
console.log(event.key);
console.log(cardElement);
console.log("Now printing event target");
console.log(event.target);
if (event.target === cardElement && event.key === 'Escape') {
this.handleCancel();
}
}
handleSave() {
const tinyMceEditor = this.template.querySelector('builder_omnistudio_common-rich-text-editor');
const content = tinyMceEditor.getContent();
const saveEvent = new CustomEvent('close', {
detail : content
});
this.dispatchEvent(saveEvent);
}
handleCancel() {
this.dispatchEvent(new CustomEvent('close'));
}
}