<button onclick={openConfirm}>openConfirm</button>
import { LightningElement } from 'lwc';
import { alert, confirm } from './deModal';
export default class Lwc036ReuseModal extends LightningElement {
openConfirm(){
confirm('알럿 메세지').then(isConfirm => {
console.log('isConfirm : ', isConfirm);
});
}
}
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>57.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
<target>lightning__RecordPage</target>
<target>lightning__HomePage</target>
<target>lightningCommunity__Page</target>
<target>lightningCommunity__Default</target>
</targets>
</LightningComponentBundle>
deModal.js파일을 만들어 위와 같은 구조로 만들었습니다.
// 커스텀 Confirm 모달
const confirm = (title) => {
if (!window._isOpenConfirmModal) {
window._isOpenConfirmModal = true;
return new Promise((resolve) => {
// modal을 새로 만들어 body태그에 추가하고,
// body 태그에 aside태그로 감싸인 modal이 추가되면 active class를 추가해 보이게 함
let confirmModal = document.createElement("aside");
confirmModal.classList.add("confirm-modal");
confirmModal.innerHTML = `
<div class="confirm-container">
<style>${alertConfirmStyle}</style>
<div class="confirm-body">
<h5 class="ca-title">${title}</h5>
</div>
<div class="confirm-bottom">
<button type="button" class="cancel">취소</button>
<button type="button" class="confirm">확인</button>
</div>
</div>`;
document.body.appendChild(confirmModal);
setTimeout(function () {
document
.querySelector(".confirm-modal")
.classList.add("active");
}, 150);
// 모달이 만들어지면, 버튼에 onclick 이벤트를 추가
let buttons = confirmModal.querySelectorAll(
".confirm-bottom > button"
);
buttons.forEach((item, idx) => {
// 확인을 눌렀으면 true, 취소를 눌렀으면 false 반환
let isConfirm = item.classList.contains("confirm");
item.addEventListener("click", () => {
setResolve(isConfirm);
});
});
// 확인, 또는 취소를 눌러 모달을 닫음
function setResolve(bool) {
document
.querySelector(".confirm-modal")
.classList.remove("active");
setTimeout(function () {
document.querySelector(".confirm-modal").remove();
window._isOpenConfirmModal = false;
resolve(bool);
}, 350);
}
});
}
}
export {
alert,
confirm
}
const alertConfirmStyle = `
.confirm-modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background-color: rgba(0,0,0,0.5);
padding: 20px 0;
z-index: 999999;
}
.confirm-modal .confirm-container {
background-color: white;
width: 500px;
max-width: calc(100% - 40px);
max-height: 100%;
text-align: center;
overflow-y: auto;
opacity: 0;
transform: scale(0.85);
transition: all 0.25s;
padding: 20px;
}
.confirm-modal.active .confirm-container {
opacity: 1;
transform: none;
}
`;
뒷 배경은 무시해주세요
↑ GIF입니다 안보이면 새로고침
+) 만약 transform: scale(0.85);이 없다면 화면이 어색해집니다.
↑ GIF입니다 안보이면 새로고침
+) 컴포넌트 안에 JS를 만드는 것이 아닌, 다른 컴포넌트에 넣고 공용으로 사용하고 싶으면 deModal이라는 컴포넌트를 따로 만들고, 버튼이 있는 컴포넌트의 JS에서 다음과 같이 불러옵니다.
import { alert, confirm } from 'c/deModal';