JSFiddle - React, Tailwind, and code Playground

HTML

<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
  <button class="alert">Do stuff</button>
</body>

<template id="modal_template">
    <div class="modal_background">
        <div class="modal_content">
            <h2 class="modal_header"></h2>
            <p class="modal_message"></p>
            <button class="modal_button modal_accept_button"></button>
        </div>
    </div>
</template>
</html>

CSS

*{
  background-color: #333;
}
.modal_background {
    position: fixed;
    z-index: 2;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    overflow: auto;
    background-color: rgba(0, 0, 0, 0.4);
}
.modal_content {
    background-color: #222;
    max-height: calc(100vh - 100px);
    padding: 20px;
    margin: 20px auto;
    width: 80%;
}

JavaScript

async function display_modal(title, message, button_label = "Accept") {
  // resolve promise when accept is clicked
  return new Promise((resolve) => {
    
    // create a modal from template
    const temp = document.querySelector("#modal_template");
    let clone = temp.content.cloneNode(true);
    clone.querySelector(".modal_header").innerText = title;
    clone.querySelector(".modal_message").innerText = message;

    // create an accept button
    const button = clone.querySelector(".modal_accept_button");
    button.innerText = button_label;
    button.addEventListener("click", (e) => {
      // On click, delete modal and resolve the promise
      const modal_background = e.srcElement.parentNode.parentNode;
      modal_background.parentNode.removeChild(modal_background);
      resolve();
    });

    document.body.appendChild(clone);
  });
}

window.onload = () => {
  const alert = document.querySelector(".alert");
  alert.addEventListener("click", () => {
    display_modal("Alert", "Important message", "Accept").then(console.log("Accept button clicked"));
  });
}